// import com.alibaba.druid.sql.ast.*;
// import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
// import com.alibaba.druid.sql.dialect.oracle.ast.OracleSegmentAttributes;
// import com.alibaba.druid.sql.visitor.SQLASTVisitor;
// import com.alibaba.druid.util.FnvHash;

// import java.util.ArrayList;
// import java.util.List;

#include "SQLCreateMaterializedViewStatement.h"
#include "../../visitor/SQLASTVisitor.h"
#include "../../../utils/FnvHash.h"
#include "../../../utils/instanceof.h"
#include "../../../utils/listTran.h"
#include "../SQLPartitionBy.h"
#include "SQLAssignItem.h"
#include "SQLSelect.h"
#include "../expr/SQLIdentifierExpr.h"
#include "SQLTableElement.h"

SQLCreateMaterializedViewStatement::SQLCreateMaterializedViewStatement()
{
  columns = std::make_shared<std::list<SQLName_ptr>>();
  tableElementList = std::make_shared<std::list<SQLTableElement_ptr>>();
  distributedBy = std::make_shared<std::list<SQLName_ptr>>();
  tableOptions = std::make_shared<std::list<SQLAssignItem_ptr>>();
  partitionedOn = std::make_shared<std::list<SQLName_ptr>>();
}

SQLName_ptr SQLCreateMaterializedViewStatement::getName()
{
  return name;
}

void SQLCreateMaterializedViewStatement::setName(SQLName_ptr name)
{
  if (name != nullptr)
  {
    name->setParent(SharedObject(SQLCreateMaterializedViewStatement));
  }
  this->name = name;
}

BOOL_ptr SQLCreateMaterializedViewStatement::isIfNotExists()
{
  return ifNotExists;
}

void SQLCreateMaterializedViewStatement::setIfNotExists(BOOL_ptr ifNotExists)
{
  this->ifNotExists = ifNotExists;
}

SQLName_list_ptr SQLCreateMaterializedViewStatement::getColumns()
{
  return columns;
}

SQLSelect_ptr SQLCreateMaterializedViewStatement::getQuery()
{
  return query;
}

void SQLCreateMaterializedViewStatement::setQuery(SQLSelect_ptr query)
{
  if (query != nullptr)
  {
    query->setParent(SharedObject(SQLCreateMaterializedViewStatement));
  }
  this->query = query;
}

BOOL_ptr SQLCreateMaterializedViewStatement::isBuildImmediate()
{
  return buildImmediate;
}

void SQLCreateMaterializedViewStatement::setBuildImmediate(BOOL_ptr buildImmediate)
{
  this->buildImmediate = buildImmediate;
}

BOOL_ptr SQLCreateMaterializedViewStatement::isBuildDeferred()
{
  return buildDeferred;
}

void SQLCreateMaterializedViewStatement::setBuildDeferred(BOOL_ptr buildDeferred)
{
  this->buildDeferred = buildDeferred;
}

BOOL_ptr SQLCreateMaterializedViewStatement::isRefresh()
{
  return (this->refreshFast || refreshComplete || refreshForce || refreshOnDemand || refreshOnCommit || refreshStartWith || refreshNext)?BOOL::TRUE:BOOL::FALSE;
}

BOOL_ptr SQLCreateMaterializedViewStatement::isRefreshFast()
{
  return refreshFast;
}

void SQLCreateMaterializedViewStatement::setRefreshFast(BOOL_ptr refreshFast)
{
  this->refreshFast = refreshFast;
}

BOOL_ptr SQLCreateMaterializedViewStatement::isRefreshComplete()
{
  return refreshComplete;
}

void SQLCreateMaterializedViewStatement::setRefreshComplete(BOOL_ptr refreshComplete)
{
  this->refreshComplete = refreshComplete;
}

BOOL_ptr SQLCreateMaterializedViewStatement::isRefreshForce()
{
  return refreshForce;
}

void SQLCreateMaterializedViewStatement::setRefreshForce(BOOL_ptr refreshForce)
{
  this->refreshForce = refreshForce;
}

BOOL_ptr SQLCreateMaterializedViewStatement::isRefreshOnCommit()
{
  return refreshOnCommit;
}

void SQLCreateMaterializedViewStatement::setRefreshOnCommit(BOOL_ptr refreshOnCommit)
{
  this->refreshOnCommit = refreshOnCommit;
}

BOOL_ptr SQLCreateMaterializedViewStatement::isRefreshOnDemand()
{
  return refreshOnDemand;
}

void SQLCreateMaterializedViewStatement::setRefreshOnDemand(BOOL_ptr refreshOnDemand)
{
  this->refreshOnDemand = refreshOnDemand;
}

BOOL_ptr SQLCreateMaterializedViewStatement::isRefreshOnOverWrite()
{
  return refreshOnOverWrite;
}

void SQLCreateMaterializedViewStatement::setRefreshOnOverWrite(BOOL_ptr refreshOnOverWrite)
{
  this->refreshOnOverWrite = refreshOnOverWrite;
}

BOOL_ptr SQLCreateMaterializedViewStatement::isRefreshStartWith()
{
  return refreshStartWith;
}

void SQLCreateMaterializedViewStatement::setRefreshStartWith(BOOL_ptr refreshStartWith)
{
  this->refreshStartWith = refreshStartWith;
}

BOOL_ptr SQLCreateMaterializedViewStatement::isRefreshNext()
{
  return refreshNext;
}

void SQLCreateMaterializedViewStatement::setRefreshNext(BOOL_ptr refreshNext)
{
  this->refreshNext = refreshNext;
}

int SQLCreateMaterializedViewStatement::getPctfree()
{
  return pctfree;
}

void SQLCreateMaterializedViewStatement::setPctfree(int pctfree)
{
  this->pctfree = pctfree;
}

int SQLCreateMaterializedViewStatement::getPctused()
{
  return pctused;
}

void SQLCreateMaterializedViewStatement::setPctused(int pctused)
{
  this->pctused = pctused;
}

int SQLCreateMaterializedViewStatement::getInitrans()
{
  return initrans;
}

void SQLCreateMaterializedViewStatement::setInitrans(int initrans)
{
  this->initrans = initrans;
}

int SQLCreateMaterializedViewStatement::getMaxtrans()
{
  return maxtrans;
}

void SQLCreateMaterializedViewStatement::setMaxtrans(int maxtrans)
{
  this->maxtrans = maxtrans;
}

int SQLCreateMaterializedViewStatement::getPctincrease()
{
  return pctincrease;
}

void SQLCreateMaterializedViewStatement::setPctincrease(int pctincrease)
{
  this->pctincrease = pctincrease;
}

int SQLCreateMaterializedViewStatement::getFreeLists()
{
  return freeLists;
}

void SQLCreateMaterializedViewStatement::setFreeLists(int freeLists)
{
  this->freeLists = freeLists;
}

BOOL_ptr SQLCreateMaterializedViewStatement::getCompress()
{
  return compress;
}

void SQLCreateMaterializedViewStatement::setCompress(BOOL_ptr compress)
{
  this->compress = compress;
}

int SQLCreateMaterializedViewStatement::getCompressLevel()
{
  return compressLevel;
}

void SQLCreateMaterializedViewStatement::setCompressLevel(int compressLevel)
{
  this->compressLevel = compressLevel;
}

BOOL_ptr SQLCreateMaterializedViewStatement::isCompressForOltp()
{
  return compressForOltp;
}

void SQLCreateMaterializedViewStatement::setCompressForOltp(BOOL_ptr compressForOltp)
{
  this->compressForOltp = compressForOltp;
}

int SQLCreateMaterializedViewStatement::getPctthreshold()
{
  return pctthreshold;
}

void SQLCreateMaterializedViewStatement::setPctthreshold(int pctthreshold)
{
  this->pctthreshold = pctthreshold;
}

BOOL_ptr SQLCreateMaterializedViewStatement::getLogging()
{
  return logging;
}

void SQLCreateMaterializedViewStatement::setLogging(BOOL_ptr logging)
{
  this->logging = logging;
}

SQLName_ptr SQLCreateMaterializedViewStatement::getTablespace()
{
  return tablespace;
}

void SQLCreateMaterializedViewStatement::setTablespace(SQLName_ptr tablespace)
{
  if (tablespace != nullptr)
  {
    tablespace->setParent(SharedObject(SQLCreateMaterializedViewStatement));
  }
  this->tablespace = tablespace;
}

SQLObject_ptr SQLCreateMaterializedViewStatement::getStorage()
{
  return storage;
}

void SQLCreateMaterializedViewStatement::setStorage(SQLObject_ptr storage)
{
  if (storage != nullptr)
  {
    storage->setParent(SharedObject(SQLCreateMaterializedViewStatement));
  }
  this->storage = storage;
}

BOOL_ptr SQLCreateMaterializedViewStatement::getParallel()
{
  return parallel;
}

void SQLCreateMaterializedViewStatement::setParallel(BOOL_ptr parallel)
{
  this->parallel = parallel;
}

int SQLCreateMaterializedViewStatement::getParallelValue()
{
  return parallelValue;
}

void SQLCreateMaterializedViewStatement::setParallelValue(int parallelValue)
{
  this->parallelValue = parallelValue;
}

BOOL_ptr SQLCreateMaterializedViewStatement::getEnableQueryRewrite()
{
  return enableQueryRewrite;
}

void SQLCreateMaterializedViewStatement::setEnableQueryRewrite(BOOL_ptr enableQueryRewrite)
{
  this->enableQueryRewrite = enableQueryRewrite;
}

BOOL_ptr SQLCreateMaterializedViewStatement::getCache()
{
  return cache;
}

void SQLCreateMaterializedViewStatement::setCache(BOOL_ptr cache)
{
  this->cache = cache;
}

SQLPartitionBy_ptr SQLCreateMaterializedViewStatement::getPartitionBy()
{
  return partitionBy;
}

SQLTableElement_list_ptr SQLCreateMaterializedViewStatement::getTableElementList()
{
  return tableElementList;
}

SQLName_list_ptr SQLCreateMaterializedViewStatement::getDistributedBy()
{
  return distributedBy;
}

SQLName_ptr SQLCreateMaterializedViewStatement::getDistributedByType()
{
  return distributedByType;
}

void SQLCreateMaterializedViewStatement::setDistributedByType(SQLName_ptr x)
{
  if (x != nullptr)
  {
    x->setParent(SharedObject(SQLCreateMaterializedViewStatement));
  }
  this->distributedByType = x;
}

SQLExpr_ptr SQLCreateMaterializedViewStatement::getStartWith()
{
  return startWith;
}

void SQLCreateMaterializedViewStatement::setStartWith(SQLExpr_ptr x)
{
  if (x != nullptr)
  {
    x->setParent(SharedObject(SQLCreateMaterializedViewStatement));
  }
  this->startWith = x;
}

SQLExpr_ptr SQLCreateMaterializedViewStatement::getNext()
{
  return next;
}

void SQLCreateMaterializedViewStatement::setNext(SQLExpr_ptr x)
{
  if (x != nullptr)
  {
    x->setParent(SharedObject(SQLCreateMaterializedViewStatement));
  }
  this->next = x;
}

void SQLCreateMaterializedViewStatement::setPartitionBy(SQLPartitionBy_ptr x)
{
  if (x != nullptr)
  {
    x->setParent(SharedObject(SQLCreateMaterializedViewStatement));
  }
  this->partitionBy = x;
}

BOOL_ptr SQLCreateMaterializedViewStatement::isWithRowId()
{
  return withRowId;
}

void SQLCreateMaterializedViewStatement::setWithRowId(BOOL_ptr withRowId)
{
  this->withRowId = withRowId;
}

SQLName_list_ptr SQLCreateMaterializedViewStatement::getPartitionedOn()
{
  return partitionedOn;
}

void SQLCreateMaterializedViewStatement::addOption(string_ptr name, SQLExpr_ptr value)
{
  SQLAssignItem_ptr assignItem = SQLAssignItem_ptr(new SQLAssignItem(SQLIdentifierExpr_ptr(new SQLIdentifierExpr(name)), value));
  assignItem->setParent(SharedObject(SQLCreateMaterializedViewStatement));
  tableOptions->push_back(assignItem);
}

SQLAssignItem_list_ptr SQLCreateMaterializedViewStatement::getTableOptions()
{
  return tableOptions;
}

SQLExpr_ptr SQLCreateMaterializedViewStatement::getOption(string_ptr name)
{
  if (name == nullptr)
  {
    return nullptr;
  }

  long hash64 = FnvHash::hashCode64(name);

  for (SQLAssignItem_ptr item : *tableOptions)
  {
    SQLExpr_ptr target = item->getTarget();
    if (instanceof <SQLExpr, SQLIdentifierExpr>(target))
    {
      if ((std::dynamic_pointer_cast<SQLIdentifierExpr>(target))->hashCode64() == hash64)
      {
        return item->getValue();
      }
    }
  }

  return nullptr;
}

SQLExpr_ptr SQLCreateMaterializedViewStatement::getComment()
{
  return comment;
}

void SQLCreateMaterializedViewStatement::setComment(SQLExpr_ptr x)
{
  if (x != nullptr)
  {
    x->setParent(SharedObject(SQLCreateMaterializedViewStatement));
  }
  this->comment = x;
}

SQLExpr_ptr SQLCreateMaterializedViewStatement::getLifyCycle()
{
  return lifyCycle;
}

void SQLCreateMaterializedViewStatement::setLifyCycle(SQLExpr_ptr x)
{
  if (x != nullptr)
  {
    x->setParent(SharedObject(SQLCreateMaterializedViewStatement));
  }
  this->lifyCycle = x;
}

// @Override
void SQLCreateMaterializedViewStatement::accept0(SQLASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(SQLCreateMaterializedViewStatement)))
  {
    acceptChild(visitor, name);
    SQLObject_list_ptr tmp1 = ListTran::tran_class<SQLName, SQLObject>(columns);
    acceptChild(visitor, tmp1);
    acceptChild(visitor, partitionBy);
    acceptChild(visitor, query);
    SQLObject_list_ptr tmp2 = ListTran::tran_class<SQLTableElement, SQLObject>(tableElementList);
    acceptChild(visitor, tmp2);
    SQLObject_list_ptr tmp3 = ListTran::tran_class<SQLName, SQLObject>(distributedBy);
    acceptChild(visitor, tmp3);
    acceptChild(visitor, distributedByType);
    acceptChild(visitor, startWith);
    acceptChild(visitor, next);
    SQLObject_list_ptr tmp4 = ListTran::tran_class<SQLAssignItem, SQLObject>(tableOptions);
    acceptChild(visitor, tmp4);
    acceptChild(visitor, comment);
  }
  visitor->endVisit(SharedObject(SQLCreateMaterializedViewStatement));
}

// @Override
BOOL_ptr SQLCreateMaterializedViewStatement::replace(SQLExpr_ptr expr, SQLExpr_ptr target)
{
  if (expr == name)
  {
    setName(std::dynamic_pointer_cast<SQLName>(target));
    return BOOL::TRUE;
  }
  if (expr == next)
  {
    setNext(target);
    return BOOL::TRUE;
  }
  if (expr == startWith)
  {
    setStartWith(target);
    return BOOL::TRUE;
  }
  return BOOL::FALSE;
}
